﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DrawerGeneral;
using System.Windows.Media;

namespace DrawerServer
{
    public class RemoteObject : MarshalByRefObject, IRemote
    {        
        #region TestWrite

        void IRemote.TestWrite(string SenderIP, string cont)
        {
            ServerStartup.sf.AppendTextToDisplay(SenderIP + ": " + cont);
        }

        #endregion
        
        #region Client disconnected
        /// <summary>
        /// Call when client want to disconnect from server
        /// </summary>
        /// <param name="Sender">Name of the client who want to disconnect</param>
        /// 
        public void ClientDisconnect(string Sender)
        {
            ServerStartup.sf.AppendTextToDisplay(Sender + " disconnected");
            //throw new NotImplementedException();
        }

        #endregion

        #region Register WrapperTransporterClass from client to server, server use this wrapper to send message to client
        /// <summary>
        /// Get WrapperTransporterClass from client and add it to the lists.
        /// This wrapper class is used to send message from server to client.
        /// </summary>
        /// <param name="Sender">Name of the client who send this WrapperTransporterClass</param>
        /// <param name="wtc">Wrapper class, used to send message from server to client.</param>
        /// 
        public void RegisterWrapperTransporterClass(string Sender, WrapperTransporterClass wtc)
        {
            ServerStartup.sf.ConnectingClientList.Add(Sender);
            ServerStartup.sf.ToClientChannels.Add(Sender, wtc);
        }

        #endregion

        #region IRemote Members

        /// <summary>
        /// Send canvas changed event
        /// </summary>
        /// <param name="Sender"></param>
        /// <param name="e"></param>
        public void DispatchCanvasChangedEvent(string Sender, Drawer.Controls.CanvasChildrenChangeEventArgs e)
        {
            //ServerStartup.sf.AppendTextToDisplay("get canvas event from client " + Sender + "\n");
            //ServerStartup.sf.AppendTextToDisplay("source code: RemoteObject.cs, method DispatchCanvasChangedEvent\n");
            if (!string.IsNullOrEmpty(e.VisualAdded))
            {
                ///**********/
                //ServerStartup.sf.IndexMap.Add(Sender + "_" + e.ChangedIndex, ServerStartup.sf.DrawCanvasChildrenCount);
                //ServerStartup.sf.DrawCanvas.AddChild(Sender, e.VisualAdded, ServerStartup.sf.DrawCanvasChildrenCount);
                //ServerStartup.sf.DrawCanvasChildrenCount++;
                ///**********/
                ServerStartup.sf.DrawCanvas.AddChild(Sender, e.VisualAdded, e.ChangedIndex);
                
                ServerStartup.sf.AppendTextToDisplay("Add: " + e.ChangedIndex);

                foreach (String ClientNameString in ServerStartup.sf.ConnectingClientList)
                {
                    if (!ClientNameString.Equals(Sender))
                    {
                        DelegateAddVisualElementTransporter g = new DelegateAddVisualElementTransporter(((WrapperTransporterClass)ServerStartup.sf.ToClientChannels[ClientNameString]).RunAddVisualElementTransporter);
                        g.BeginInvoke(e, new AsyncCallback(DoNothingCallback), null);
                        //((WrapperTransporterClass)ServerStartup.sf.ToClientChannels[ClientNameString]).RunAddVisualElementTransporter(e);
                    }
                }
            }
            else if (!string.IsNullOrEmpty(e.VisualRemoved))
            {
                ServerStartup.sf.DrawCanvas.RemoveChild(Sender, e.VisualRemoved, e.ChangedIndex);
                ///**********/
                //int removeIndex;
                //removeIndex = (int)ServerStartup.sf.IndexMap[Sender + "_" + e.ChangedIndex];
                //ServerStartup.sf.DrawCanvas.RemoveChild(Sender, e.VisualRemoved, removeIndex);
                //ServerStartup.sf.DrawCanvasChildrenCount--;
                ///**********/

                foreach (String ClientNameString in ServerStartup.sf.ConnectingClientList)
                {
                    if (!ClientNameString.Equals(Sender))
                    {
                        DelegateRemoveVisualElementTransporter g = new DelegateRemoveVisualElementTransporter(((WrapperTransporterClass)ServerStartup.sf.ToClientChannels[ClientNameString]).RunRemoveVisualElementTransporter);
                        g.BeginInvoke(e, new AsyncCallback(DoNothingCallback), null);
                        
                    }
                }
                
                ServerStartup.sf.AppendTextToDisplay("Remove: " + e.ChangedIndex);
            }
            System.Console.WriteLine(e.ChangedIndex);
            
        }

        public void DispatchCanvasEditedEvent(string Sender, Drawer.Controls.CanvasChildEditEventArgs e)
        {
            if (!string.IsNullOrEmpty(e.UpdateChild))
            {
                ServerStartup.sf.DrawCanvas.UpdateChild(Sender, e.UpdateChild, e.Index);
                ///*********/
                //int updatedIndex;
                //updatedIndex = (int)ServerStartup.sf.IndexMap[Sender + "_" + e.Index];
                //ServerStartup.sf.DrawCanvas.UpdateChild(Sender, e.UpdateChild, updatedIndex);
                ///*********/
                foreach (String ClientNameString in ServerStartup.sf.ConnectingClientList)
                {
                    if (!ClientNameString.Equals(Sender))
                    {
                        DelegateEditVisualElementTransporter g = new DelegateEditVisualElementTransporter(((WrapperTransporterClass)ServerStartup.sf.ToClientChannels[ClientNameString]).RunEditVisualElementTransporter);
                        g.BeginInvoke(e, new AsyncCallback(DoNothingCallback), null);
                        //((WrapperTransporterClass)ServerStartup.sf.ToClientChannels[ClientNameString]).RunAddVisualElementTransporter(e);
                    }
                }
            }
            System.Console.WriteLine("Update:" + e.Index);
            ServerStartup.sf.AppendTextToDisplay("Update: " + e.Index);

            
        }

        public CanvasElementsAndFillColor GetFillColorAndCurrentCanvas(String Sender)
        {
            Random r = new Random();
            int red = r.Next(0, byte.MaxValue + 1);
            int green = r.Next(0, byte.MaxValue + 1);
            int blue = r.Next(0, byte.MaxValue + 1);
            Color c = Color.FromArgb(255, (byte)red, (byte)green, (byte)blue);
            //ServerStartup.sf.AppendTextToDisplay(c.ToString());
            
            CanvasElementsAndFillColor res = new CanvasElementsAndFillColor();
            res.ColorCode = c.ToString();
            res.Elements = ServerStartup.sf.DrawCanvas.GetCanvasElementList();

            return res;

            //return (Brush)(new SolidColorBrush(Color.FromArgb(255, (byte)red, (byte)green, (byte)blue)));
        }

        #endregion

        public void DoNothingCallback(IAsyncResult res)
        {
            if (!res.IsCompleted)
            {
                ServerStartup.sf.AppendTextToDisplay("Not complete");
            }
            else
            {
                ServerStartup.sf.AppendTextToDisplay("Complete");
            }
        }
    }
}
